﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data.SqlClient;
using System.Data;
using TSL_Tools.SqlTools;
using ReportingEngine;
using System.Xml;
using System.Xml.Linq;
using System.Windows.Forms.DataVisualization.Charting;
using System.IO;

namespace VSLT_Reporting
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        #region -- Document Formatting Properties -----------------------------------------------------------------------
        //TextElement te;
        #endregion

        public static string FormatXML(string inputString)
        {
            // Reformat XML in something that is easier to read
            string sRet = "";
            try
            {
                XDocument xdoc = XDocument.Parse(inputString);

                sRet = ((xdoc.Declaration == null) ? "" : xdoc.Declaration.ToString() + "\n") + xdoc.ToString(SaveOptions.None);
            }
            catch (XmlException xmlEx)
            {
                MessageBox.Show(String.Format(Msg_XMLFORMATTINGERRORMSG,xmlEx.Message), Msg_XMLFORMATTINGERRORTITLE);
            }
            return sRet;
        }

        // ADDED TO REPORTING_GENERATOR
        private void AddSectionTitleToReport(string titleString)
        {
            FlowDocument flowDoc = rtbResults.Document;

            //// Create bolded text.
            //Run run = new Run();
            //run.Text = titleString;

            //// Add three parts of sentence to a paragraph, in order.
            //Paragraph paragraph = new Paragraph();
            //FontFamilyValueSerializer ffvs = new FontFamilyValueSerializer();            
            ////paragraph.FontFamily = ffvs.ConvertFromString("Segoe UI Light"
            //paragraph.FontSize = 21.33;
            //paragraph.TextDecorations = TextDecorations.Underline;
            //paragraph.Inlines.Add(run);

            // Create a document and add this paragraph.
            flowDoc.Blocks.Add(ReportGenerator.TSL_ReportGenerator.AddSectionTitleToReport(titleString));
            rtbResults.UpdateLayout();
        }

        private void AddQuickTextToReport(string textString)
        {
            FlowDocument flowDoc = rtbResults.Document;

            // Create bolded text.
            Run run = new Run();
            //run.Text = "\r\n" + titleString + "\r\n";
            run.Text = "\r\n" + textString + "\r\n";

            // Add three parts of sentence to a paragraph, in order.
            Paragraph paragraph = new Paragraph();
            FontFamilyValueSerializer ffvs = new FontFamilyValueSerializer();
            //paragraph.FontFamily = ffvs.ConvertFromString("Segoe UI Light"
            paragraph.FontSize = 14.66;
            paragraph.TextDecorations = TextDecorations.Underline;
            paragraph.Inlines.Add(run);

            // Create a document and add this paragraph.
            flowDoc.Blocks.Add(paragraph);
            rtbResults.UpdateLayout();
            //<Paragraph FontFamily="Segoe UI Light" FontSize="21.333333333333332" Margin="0,10.67,0,0">
        }

        private void AddSeparatorLinesToReport(int numberOfLines)
        {
            StringBuilder sb = new StringBuilder();
            for (int x = 0; x < numberOfLines; x++)
            {
                sb.Append("\r\n");
            }
            FlowDocument flowDoc = rtbResults.Document;

            // Create bolded text.
            Run run = new Run();
            run.Text = sb.ToString();

            // Add three parts of sentence to a paragraph, in order.
            Paragraph paragraph = new Paragraph();
            FontFamilyValueSerializer ffvs = new FontFamilyValueSerializer();
            paragraph.FontSize = 21.33;
            paragraph.Inlines.Add(run);

            // Create a document and add this paragraph.
            flowDoc.Blocks.Add(paragraph);
            rtbResults.UpdateLayout();
        }

        // ADDED TO REPORTING_GENERATOR
        private void AddDebugTimingInfoToReport()
        {
            FlowDocument flowDoc = rtbResults.Document;

            List listx = new List();
            // Set the space between the markers and list content to 25 DIP.
            listx.MarkerOffset = 15;
            
            // Use uppercase Roman numerals.
            listx.MarkerStyle = TextMarkerStyle.Disc;
            // Start list numbering at 5.
            //listx.StartIndex = 5;
            
            foreach (string str in debugTimingInfo.ToString().Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
            {
                Paragraph paragraph = new Paragraph();
                paragraph.Inlines.Add(new Bold(new Run(str.Substring(0, str.IndexOf(":") + 1))));
                paragraph.Inlines.Add(new Run(str.Substring(str.IndexOf(":") + 1)));

                ListItem liV = new ListItem(paragraph);
                listx.ListItems.Add(liV);
            }

            // Create a document and add this paragraph.
            flowDoc.Blocks.Add(listx);
            rtbResults.UpdateLayout();
        }

        // ADDED TO REPORTING_GENERATOR
        private void AddCurrentChartToReport()
        {
            Chart chart = this.FindName("MyWinformChart") as Chart;
            using (MemoryStream ms = new MemoryStream())
            {
                chart.SaveImage(ms, System.Windows.Forms.DataVisualization.Charting.ChartImageFormat.Png);
                System.Drawing.Bitmap bm2 = new System.Drawing.Bitmap(ms);
                bm2.SetResolution(300, 300);
                using (MemoryStream ms2 = new MemoryStream())
                {
                    bm2.Save(ms2, System.Drawing.Imaging.ImageFormat.Png);

                    BitmapImage bi = new BitmapImage();
                    bi.BeginInit();
                    bi.CacheOption = BitmapCacheOption.OnLoad;
                    bi.StreamSource = ms2;
                    bi.EndInit();

                    System.Windows.Controls.Image _image = new System.Windows.Controls.Image();
                    _image.Source = bi;
                    _image.HorizontalAlignment = HorizontalAlignment.Left;
                    _image.Stretch = Stretch.None;
                    _image.Width = bi.Width;
                    _image.Height = bi.Height;


                    Paragraph paragraph = new Paragraph();
                    paragraph.Inlines.Add(_image);

                    // Create a document and add this paragraph.
                    FlowDocument flowDoc = rtbResults.Document;
                    flowDoc.Blocks.Add(paragraph);
                    rtbResults.UpdateLayout();
                }
            }

        }

        private void ClearReportTab()
        {
            TextRange text = new TextRange(rtbResults.Document.ContentStart, rtbResults.Document.ContentEnd);
            text.Text = "";
        }

        private FlowDocument CreateXamlTableFromDataTable(string tableTitle, DataTable dataTable)
        {
            List<int> widths = new List<int>(new int[] { 75,75,75,75,75,75,75,75,75,75 });
            return CreateXamlTableFromDataTable(tableTitle, dataTable, widths);
        }

        // ADDED TO REPORTING_GENERATOR
        private FlowDocument CreateXamlTableFromDataTable(string tableTitle, DataTable dataTable, List<int> columnWidths)
        {
            // Create the parent FlowDocument...
            int currentRowNumber = 0;
            FlowDocument flowDoc = new FlowDocument();

            // Create the Table...
            Table table1 = new Table();
            // ...and add it to the FlowDocument Blocks collection.
            flowDoc.Blocks.Add(table1);

            // Set some global formatting properties for the table.
            ThicknessConverter tc = new ThicknessConverter();

            table1.CellSpacing = 0;
            table1.Background = Brushes.White;
            table1.BorderBrush = Brushes.Black;
            //table1.BorderThickness = (Thickness)tc.ConvertFromString("0.0125in");

            int numberOfColumns = dataTable.Columns.Count;
            for (int x = 0; x < numberOfColumns; x++)
            {
                TableColumn col = new TableColumn();

                int widthColumnIndex = x % columnWidths.Count;
                col.Width = new GridLength(columnWidths[widthColumnIndex]);
                table1.Columns.Add(col);
            }

            // Create and add an empty TableRowGroup to hold the table's Rows.       
            table1.RowGroups.Add(new TableRowGroup());

            TableRow currentRow;

            #region -- header row (not currently being used) ------------------------------------------------
            //// Add the first (title) row.
            //table1.RowGroups[0].Rows.Add(new TableRow());

            //// Alias the current working row for easy reference.
            //currentRow = table1.RowGroups[0].Rows[currentRowNumber++];

            //// Global formatting for the title row.
            //currentRow.Background = Brushes.LightBlue;
            //currentRow.FontSize = 16;
            //currentRow.FontWeight = System.Windows.FontWeights.Bold;

            //// Add the header row with content, 
            //currentRow.Cells.Add(new TableCell(new Paragraph(new Run(tableTitle))));
            //// and set the row to span all 6 columns.
            //currentRow.Cells[0].ColumnSpan = 6;
            #endregion

            // Add the second (header) row.
            table1.RowGroups[0].Rows.Add(new TableRow());
            currentRow = table1.RowGroups[0].Rows[currentRowNumber++];

            // Global formatting for the header row.
            currentRow.FontSize = 9;
            currentRow.FontWeight = FontWeights.Bold;
            
            
            // Add cells with content to the second row.
            foreach (DataColumn column in dataTable.Columns)
            {
                TableCell cell1 = new TableCell(new Paragraph(new Run(column.ColumnName)));
                cell1.BorderBrush = Brushes.Black;
                cell1.Background = Brushes.Gainsboro;
                cell1.BorderThickness = (Thickness)tc.ConvertFromString("1pt");
                cell1.Padding = new Thickness(2); //(Thickness)tc.ConvertFromString("1pt");
                currentRow.Cells.Add(cell1);
            }

            // Add the data.
            foreach (DataRow row in dataTable.Rows)
            {
                table1.RowGroups[0].Rows.Add(new TableRow());
                currentRow = table1.RowGroups[0].Rows[currentRowNumber++];

                // Global formatting for the row.
                currentRow.FontSize = 9;
                currentRow.FontWeight = FontWeights.Normal;
                for (int x = 0; x < dataTable.Columns.Count; x++)
                {
                    TableCell cell1 = new TableCell(new Paragraph(new Run(row[x].ToString())));
                    cell1.BorderBrush = Brushes.Black;
                    cell1.Background = (currentRowNumber % 2 == 0) ? Brushes.Cyan : Brushes.White;
                    cell1.BorderThickness = (Thickness)tc.ConvertFromString("1pt");
                    cell1.Padding = new Thickness(2); //(Thickness)tc.ConvertFromString("0.025in");
                    currentRow.Cells.Add(cell1);
                }

                // Bold the first cell.
                //currentRow.Cells[0].FontWeight = FontWeights.Bold;
            }
            return flowDoc;
        }

        private FlowDocument CreateXamlDataTableFromDataTable(string tableTitle, DataTable dataTable, List<int> columnWidths)
        {
            // Create the parent FlowDocument...
            int currentRowNumber = 0;
            FlowDocument flowDoc = new FlowDocument();

            // Create the Table...
            Table table1 = new Table();
            // ...and add it to the FlowDocument Blocks collection.
            flowDoc.Blocks.Add(table1);

            // Set some global formatting properties for the table.
            ThicknessConverter tc = new ThicknessConverter();

            table1.CellSpacing = 0;
            table1.Background = Brushes.White;
            table1.BorderBrush = Brushes.Black;
            //table1.BorderThickness = (Thickness)tc.ConvertFromString("0.0125in");

            int numberOfColumns = dataTable.Columns.Count;
            for (int x = 0; x < numberOfColumns; x++)
            {
                TableColumn col = new TableColumn();

                int widthColumnIndex = x % columnWidths.Count;
                col.Width = new GridLength(columnWidths[widthColumnIndex]);
                table1.Columns.Add(col);
            }

            // Create and add an empty TableRowGroup to hold the table's Rows.       
            table1.RowGroups.Add(new TableRowGroup());

            TableRow currentRow;

            // Add the second (header) row.
            table1.RowGroups[0].Rows.Add(new TableRow());
            currentRow = table1.RowGroups[0].Rows[currentRowNumber++];

            // Global formatting for the header row.
            currentRow.FontSize = 9;
            currentRow.FontWeight = FontWeights.Bold;

            //TableCell cell = new TableCell(new Paragraph(new Run("Color")));
            //cell.BorderBrush = Brushes.Black;
            //cell.Background = Brushes.Gainsboro;
            //cell.BorderThickness = (Thickness)tc.ConvertFromString("0.0125in");
            //cell.Padding = new Thickness(2); //(Thickness)tc.ConvertFromString("0.025in");
            //currentRow.Cells.Add(cell);

            // Add cells with content to the second row.
            foreach (DataColumn column in dataTable.Columns)
            {
                TableCell cell1 = new TableCell(new Paragraph(new Run(column.ColumnName)));
                cell1.BorderBrush = Brushes.Black;
                cell1.Background = Brushes.Gainsboro;
                cell1.BorderThickness = (Thickness)tc.ConvertFromString("0.0125in");
                cell1.Padding = new Thickness(2); //(Thickness)tc.ConvertFromString("0.025in");
                currentRow.Cells.Add(cell1);
            }

            // Add the data.
            currentPlotColor = 0;
            foreach (DataRow row in dataTable.Rows)
            {
                table1.RowGroups[0].Rows.Add(new TableRow());
                currentRow = table1.RowGroups[0].Rows[currentRowNumber++];

                // Global formatting for the row.
                currentRow.FontSize = 9;
                currentRow.FontWeight = FontWeights.Normal;

                //TableCell cell0 = new TableCell(new Paragraph(new Run("")));
                //cell0.BorderBrush = Brushes.Black;
                //cell0.Background = new SolidColorBrush(Color.FromArgb(
                //    plotColors[currentPlotColor % plotColors.Count].A,
                //    plotColors[currentPlotColor % plotColors.Count].R,
                //    plotColors[currentPlotColor % plotColors.Count].G,
                //    plotColors[currentPlotColor % plotColors.Count].B));
                //cell0.BorderThickness = (Thickness)tc.ConvertFromString("0.0125in");
                //cell0.Padding = new Thickness(2); //(Thickness)tc.ConvertFromString("0.025in");
                //currentRow.Cells.Add(cell0);
                //currentPlotColor++;

                for (int x = 0; x < dataTable.Columns.Count; x++)
                {
                    TableCell cell1 = new TableCell(new Paragraph(new Run(row[x].ToString())));
                    cell1.BorderBrush = Brushes.Black;
                    cell1.Background = Brushes.White;
                    cell1.BorderThickness = (Thickness)tc.ConvertFromString("0.0125in");
                    cell1.Padding = new Thickness(2); //(Thickness)tc.ConvertFromString("0.025in");
                    currentRow.Cells.Add(cell1);
                }

                // Bold the first cell.
                //currentRow.Cells[0].FontWeight = FontWeights.Bold;
            }
            return flowDoc;
        }


        private FlowDocument CreateXamlChartTableFromDataTable(string tableTitle, DataTable dataTable, List<int> columnWidths)
        {
            // Create the parent FlowDocument...
            int currentRowNumber = 0;
            FlowDocument flowDoc = new FlowDocument();

            
            // Create the Table...
            Table table1 = new Table();
            // ...and add it to the FlowDocument Blocks collection.
            flowDoc.Blocks.Add(table1);

            // Set some global formatting properties for the table.
            ThicknessConverter tc = new ThicknessConverter();

            table1.CellSpacing = 0;
            table1.Background = Brushes.White;
            table1.BorderBrush = Brushes.Black;
            //table1.BorderThickness = (Thickness)tc.ConvertFromString("0.0125in");

            //Column for the color indicator
            TableColumn col0 = new TableColumn();
            col0.Width = new GridLength(30);
            table1.Columns.Add(col0);

            int numberOfColumns = dataTable.Columns.Count;
            for (int x = 0; x < numberOfColumns; x++)
            {
                TableColumn col = new TableColumn();

                int widthColumnIndex = x % columnWidths.Count;
                col.Width = new GridLength(columnWidths[widthColumnIndex]);                
                table1.Columns.Add(col);
            }

            // Create and add an empty TableRowGroup to hold the table's Rows.       
            table1.RowGroups.Add(new TableRowGroup());

            TableRow currentRow;

            // Add the second (header) row.
            table1.RowGroups[0].Rows.Add(new TableRow());
            currentRow = table1.RowGroups[0].Rows[currentRowNumber++];

            // Global formatting for the header row.
            currentRow.FontSize = 9;
            currentRow.FontWeight = FontWeights.Bold;

            TableCell cell = new TableCell(new Paragraph(new Run("Color")));
            cell.BorderBrush = Brushes.Black;
            cell.Background = Brushes.Gainsboro;
            cell.BorderThickness = (Thickness)tc.ConvertFromString("1pt");
            cell.Padding = new Thickness(2); //(Thickness)tc.ConvertFromString("0.025in");
            currentRow.Cells.Add(cell);

            // Add cells with content to the second row.
            foreach (DataColumn column in dataTable.Columns)
            {
                TableCell cell1 = new TableCell(new Paragraph(new Run(column.ColumnName)));
                cell1.BorderBrush = Brushes.Black;
                cell1.Background = Brushes.Gainsboro;
                cell1.BorderThickness = (Thickness)tc.ConvertFromString("1pt");
                cell1.Padding = new Thickness(2); //(Thickness)tc.ConvertFromString("0.025in");
                currentRow.Cells.Add(cell1);
            }

            // Add the data.
            currentPlotColor = 0;
            foreach (DataRow row in dataTable.Rows)
            {
                table1.RowGroups[0].Rows.Add(new TableRow());
                currentRow = table1.RowGroups[0].Rows[currentRowNumber++];

                // Global formatting for the row.
                currentRow.FontSize = 9;
                currentRow.FontWeight = FontWeights.Normal;

                TableCell cell0 = new TableCell(new Paragraph(new Run("")));
                cell0.BorderBrush = Brushes.Black;
                cell0.Background = new SolidColorBrush(Color.FromArgb(
                    plotColors[currentPlotColor % plotColors.Count].A,
                    plotColors[currentPlotColor % plotColors.Count].R,
                    plotColors[currentPlotColor % plotColors.Count].G,
                    plotColors[currentPlotColor % plotColors.Count].B));
                cell0.BorderThickness = (Thickness)tc.ConvertFromString("1pt");
                cell0.Padding = new Thickness(2); //(Thickness)tc.ConvertFromString("0.025in");
                currentRow.Cells.Add(cell0);
                currentPlotColor++;

                for (int x = 0; x < dataTable.Columns.Count; x++)
                {
                    TableCell cell1 = new TableCell(new Paragraph(new Run(row[x].ToString())));
                    cell1.BorderBrush = Brushes.Black;
                    cell1.Background = Brushes.White;
                    cell1.BorderThickness = (Thickness)tc.ConvertFromString("1pt");
                    cell1.Padding = new Thickness(2); //(Thickness)tc.ConvertFromString("0.025in");
                    currentRow.Cells.Add(cell1);
                }

                // Bold the first cell.
                //currentRow.Cells[0].FontWeight = FontWeights.Bold;
            }
            return flowDoc;
        }

        private void CopyRunResultsTableToClipboard()
        {
            dgRunResults.SelectAllCells();
            dgRunResults.ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;

            ApplicationCommands.Copy.Execute(null, dgRunResults);
            dgRunResults.UnselectAllCells();
            //tsslMessage.Content = "Table copied to clipboard";
        }

        private void CopyMainResultsTableToClipboard()
        {
            dgMainResults.SelectAllCells();
            dgMainResults.ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;

            ApplicationCommands.Copy.Execute(null, dgMainResults);
            dgMainResults.UnselectAllCells();
        }

        private FlowDocument CreateScorecardXamlTableFromDataTable(string tableTitle, DataTable dataTable)
        {
            // Create the parent FlowDocument...
            int currentRowNumber = 0;
            FlowDocument flowDoc = new FlowDocument();

            // Create the Table...
            Table table1 = new Table();
            // ...and add it to the FlowDocument Blocks collection.
            flowDoc.Blocks.Add(table1);

            // Set some global formatting properties for the table.
            ThicknessConverter tc = new ThicknessConverter();

            table1.CellSpacing = 0;
            table1.Background = Brushes.White;
            table1.BorderBrush = Brushes.Black;
            //table1.BorderThickness = (Thickness)tc.ConvertFromString("0.0125in");

            // Create 5 columns and add them to the table's Columns collection. 
            TableColumn col1 = new TableColumn();
            col1.Width = new GridLength(50);
            table1.Columns.Add(col1);

            TableColumn col2 = new TableColumn();
            col2.Width = new GridLength(200);
            table1.Columns.Add(col2);

            TableColumn col3 = new TableColumn();
            col3.Width = new GridLength(130);
            table1.Columns.Add(col3);

            TableColumn col4 = new TableColumn();
            col4.Width = new GridLength(65);
            table1.Columns.Add(col4);

            TableColumn col5 = new TableColumn();
            col5.Width = new GridLength(250);
            table1.Columns.Add(col5);

            // Create and add an empty TableRowGroup to hold the table's Rows.       
            table1.RowGroups.Add(new TableRowGroup());

            TableRow currentRow;

            // Add the first (title) row.
            table1.RowGroups[0].Rows.Add(new TableRow());

            // Alias the current working row for easy reference.
            currentRow = table1.RowGroups[0].Rows[currentRowNumber++];

            // Global formatting for the title row.
            currentRow.Background = Brushes.LightBlue;
            currentRow.FontSize = 16;
            currentRow.FontWeight = System.Windows.FontWeights.Bold;

            // Add the header row with content, 
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run(tableTitle))));
            // and set the row to span all 6 columns.
            currentRow.Cells[0].ColumnSpan = 6;

            // Add the second (header) row.
            table1.RowGroups[0].Rows.Add(new TableRow());
            currentRow = table1.RowGroups[0].Rows[currentRowNumber++];

            // Global formatting for the header row.
            currentRow.FontSize = 12;
            currentRow.FontWeight = FontWeights.Bold;


            // Add cells with content to the second row.
            foreach (DataColumn column in dataTable.Columns)
            {
                TableCell cell1 = new TableCell(new Paragraph(new Run(column.ColumnName)));
                cell1.BorderBrush = Brushes.Black;
                cell1.Background = Brushes.Gainsboro;
                cell1.BorderThickness = (Thickness)tc.ConvertFromString("1pt");
                cell1.Padding = new Thickness(2); //(Thickness)tc.ConvertFromString("0.025in");
                currentRow.Cells.Add(cell1);
            }

            // Add the data.
            foreach (DataRow row in dataTable.Rows)
            {
                table1.RowGroups[0].Rows.Add(new TableRow());
                currentRow = table1.RowGroups[0].Rows[currentRowNumber++];

                // Global formatting for the row.
                currentRow.FontSize = 12;
                currentRow.FontWeight = FontWeights.Normal;
                for (int x = 0; x < dataTable.Columns.Count; x++)
                {
                    TableCell cell1 = new TableCell(new Paragraph(new Run(row[x].ToString())));
                    cell1.BorderBrush = Brushes.Black;
                    cell1.Background = (currentRowNumber % 2 == 0) ? Brushes.Cyan : Brushes.White;
                    cell1.BorderThickness = (Thickness)tc.ConvertFromString("1pt");
                    cell1.Padding = new Thickness(2); //(Thickness)tc.ConvertFromString("0.025in");
                    currentRow.Cells.Add(cell1);
                }

                // Bold the first cell.
                //currentRow.Cells[0].FontWeight = FontWeights.Bold;
            }
            return flowDoc;
        }
    }
}
